package com.lxf.clouduser.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.lxf.clouduser.bean.GroupBean;
import com.lxf.clouduser.bean.UserGroupBean;
import com.lxf.clouduser.mapper.GroupItemRepository;
import com.lxf.clouduser.mapper.GroupMapper;
import com.lxf.clouduser.service.GroupService;
import com.lxf.clouduser.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 罗兴发
 * @data 2025/6/13 9:33
 * @description：群-业务实现类
 */
@Service
@Slf4j
public class GroupServiceImpl implements GroupService {
    @Resource
    GroupMapper groupMapper;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private GroupItemRepository groupItemRepository;

    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    /**
     * 搜索群信息
     * @param json
     * @return
     */
    @Override
    public String getGroupByGroupIdAndName(JSONObject json) {
        JSONObject js = new JSONObject();
        String groupId = json.getString("group_id");//群号
        String groupName = json.getString("group_name");//群名称
        Object o = redisUtils.get(groupId+groupName);
        if (null!=o){
            //json封装
            js.put("code",200);
            js.put("msg","Success");
            js.put("data",o);
        }else {

            Integer page = json.getInteger("page");
            Integer size = json.getInteger("size");

            // 计算初始页
            Integer startPage = (page-1)*size;

            // 1. 构建查询条件
            NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder()
                    .withQuery(QueryBuilders.multiMatchQuery(groupName, "groupName"))
                    .withQuery(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("groupId",groupId)))
                    .withPageable(PageRequest.of(startPage, size));

            // 2. 添加高亮配置
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            highlightBuilder.field("groupName")
                    .preTags("<span style='color:red'>")
                    .postTags("</span>");
            queryBuilder.withHighlightBuilder(highlightBuilder);

            // 3. 执行查询
            SearchHits<GroupBean> hits = elasticsearchRestTemplate
                    .search(queryBuilder.build(), GroupBean.class);

            // 4. 处理高亮结果
            List<GroupBean> list = hits.stream()
                    .map(hit -> {
                        GroupBean doc = hit.getContent();
                        Map<String, List<String>> highlightFields = hit.getHighlightFields();
                        highlightFields.forEach((field, texts) -> {
                            try {
                                Field declaredField = doc.getClass().getDeclaredField(field);
                                declaredField.setAccessible(true);
                                declaredField.set(doc, texts.get(0));
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        });
                        return doc;
                    }).collect(Collectors.toList());

            // 7. 构造分页结果
            PageImpl<GroupBean> group = new PageImpl<>(list, PageRequest.of(startPage, size), hits.getTotalHits());

            //json封装
            js.put("code",200);
            js.put("msg","Success");
            js.put("data",group);
            //redis缓存,有效时间4秒
            redisUtils.set(groupId+groupName,group,4);
        }
        return JSON.toJSONString(js,SerializerFeature.WriteMapNullValue);
    }

    @Override
    public String getGroupInfoByGroupId(JSONObject json) {
        JSONObject js = new JSONObject();
        String groupId = json.getString("group_id");//群号
        Object o = redisUtils.get(groupId);
        if (null!=o){
            //json封装
            js.put("code",200);
            js.put("msg","Success");
            js.put("data",o);
        }else {
            GroupBean group = groupItemRepository.findById(groupId).get();
            //json封装
            js.put("code",200);
            js.put("msg","Success");
            js.put("data",group);
            //redis缓存,有效时间4秒
            redisUtils.set(groupId,group,3);
        }
        return JSON.toJSONString(js,SerializerFeature.WriteMapNullValue);
    }

    /**
     * 仅允许群主或管理员访问该接口
     * @param json
     * @param request
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String updateGroupByGroupId(JSONObject json, HttpServletRequest request) {
        JSONObject js = new JSONObject();
        //获取请求凭证,凭证中存放用户ID和用户名，存放格式为：userId_userName
        String secretToken = request.getHeader("secretToken");

        //获取redis中缓存的token
        Object o = redisUtils.get(secretToken);
        if (null!=o){
            //截取请求头中存储的用户ID
            int secretTokenIndex = secretToken.lastIndexOf(":");
            String userIdSub = secretToken.substring(secretTokenIndex+1);
            Integer userId = Integer.valueOf(userIdSub);//用户ID
            //参数
            String groupId = json.getString("group_id");//群号
            //根据用户ID和群号查询用户身份
            UserGroupBean user = groupMapper.getGroupUserByGroupId(groupId, userId);
            if (0!=user.getUserRole()){
                String groupHead = json.getString("group_head");//群头像
                String groupName = json.getString("group_name");//群名称
                String groupNotice = json.getString("group_notice");//群公告
                //对象实例化
                GroupBean g = new GroupBean();
                g.setGroupHead(groupHead);
                g.setGroupName(groupName);
                g.setGroupId(groupId);
                g.setGroupNotice(groupNotice);
                int flag = groupMapper.updateGroupByGroupId(g);
                if (flag<0){
                    js.put("code",401);
                    js.put("msg","Update Group Info Fails");
                }else {
                    js.put("code",200);
                    js.put("msg","Success");
                    //es修改信息
                    groupItemRepository.save(g);
                }
            }else {
                js.put("code",402);
                js.put("msg","Not Operable Without Management Or Group Leader");
            }
        }else {
            js.put("code",400);
            js.put("msg","The Current Request is Invalid");
        }

        return JSON.toJSONString(js,SerializerFeature.WriteMapNullValue);
    }

}
